package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSONArray;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.heima.apis.article.IArticleClient;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.tess4j.Tess4jClient;
import com.heima.file.service.FileStorageService;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmSensitive;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmSensitiveMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.WmNewsAutoScanService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class WmNewsAutoScanServiceImpl implements WmNewsAutoScanService {


    @Autowired(required = false)
    WmNewsMapper wmNewsMapper;


    @Autowired
    private GreenTextScan greenTextScan;

    @Autowired
    private GreenImageScan greenImageScan;

    @Autowired
    private FileStorageService fileStorageService;

    @Autowired
    private IArticleClient articleClient;

    @Autowired(required = false)
    WmChannelMapper wmChannelMapper;

    @Autowired
    private WmSensitiveMapper wmSensitiveMapper;

    @Autowired
    WmUserMapper wmUserMapper;

    @Autowired
    Tess4jClient tess4jClient;


    /**
     * 自媒体文章审核
     *  1.查询数据库找到对应的news
     *  2.调用阿里云审核对应文字或图片
     *  3.使用feign调用article微服务新增数据
     * @param id  自媒体文章id
     */
    @Override
    @Async
    public void autoScanWmNews(Integer id) {
        WmNews wmNews = wmNewsMapper.selectById(id);
        if(wmNews==null){
            return;
        }
        //大目标审核文章内容
        if(wmNews.getStatus()==WmNews.Status.SUBMIT.getCode()){
            //提取内容
            Map<String,Object> map=handleTextAndImages(wmNews);
            //开始审核
            boolean isSensitive = handleSensitiveScan(map, wmNews);
            if(!isSensitive) {
                return;
            }
//            Boolean text =handleTextScan((String)map.get("text"),wmNews);
//            if(!text){
//                return;
//            }
//            Boolean images =handleImageScan((List<String>)map.get("images"),wmNews);
//            if(!images){
//                return;
//            }
            //远程调用article新增文章
            ResponseResult responseResult=saveAppArticle(wmNews);
            if(!responseResult.getCode().equals(200)){
                return;
            }

            wmNews.setArticleId((Long) responseResult.getData());
            wmNews.setStatus(WmNews.Status.PUBLISHED.getCode());
            //articleClient.saveArticle(dto);
            wmNewsMapper.updateById(wmNews);

        }

    }

    private boolean handleSensitiveScan(Map<String,Object> map, WmNews wmNews) {
        boolean flag = true;
        //获取文字
        String text = (String)map.get("text");
        //获取图片
        List<String> list = (List<String>) map.get("images");

        //获取图片中的所有文字信息
        StringBuilder sb = new StringBuilder();
        list.forEach(item->{
            if(StringUtils.isNotBlank(item)){
                byte[] bytes = fileStorageService.downLoadFile(item);
                ByteArrayInputStream image = new ByteArrayInputStream(bytes);
                try {
                    BufferedImage read = ImageIO.read(image);
                    String s = tess4jClient.doOCR(read);
                    sb.append(s);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        //获取所有的敏感词
        List<WmSensitive> wmSensitives = wmSensitiveMapper.selectList(Wrappers.<WmSensitive>lambdaQuery().select(WmSensitive::getSensitives));
        List<String> sensitiveList = wmSensitives.stream().map(WmSensitive::getSensitives).collect(Collectors.toList());
        //初始化敏感词库
        SensitiveWordUtil.initMap(sensitiveList);
        text= sb.append(text).toString();
        //查看文章中是否包含敏感词
        //Map<String, Integer> map = SensitiveWordUtil.matchWords(text);
        Map<String, Integer> stringIntegerMap = SensitiveWordUtil.matchWords(text);
        if(stringIntegerMap.size() >0){
            wmNews.setStatus(WmNews.Status.FAIL.getCode());
            wmNews.setReason("当前文章或图片中存在违规内容");
            wmNewsMapper.updateById(wmNews);
            flag = false;
        }
        return flag;
    }

    private ResponseResult saveAppArticle(WmNews wmNews) {
        ArticleDto articleDto=new ArticleDto();
        BeanUtils.copyProperties(wmNews, articleDto);
        articleDto.setLayout(wmNews.getType());
        WmChannel wmChannel = wmChannelMapper.selectById(wmNews.getChannelId());
        if(wmChannel != null){
            articleDto.setChannelName(wmChannel.getName());
        }

        //作者
        articleDto.setAuthorId(wmNews.getUserId().longValue());
        WmUser wmUser = wmUserMapper.selectById(wmNews.getUserId());
        if(wmUser != null){
            articleDto.setAuthorName(wmUser.getName());
        }

        //设置文章id
        if(wmNews.getArticleId() != null){
            articleDto.setId(wmNews.getArticleId());
        }
        articleDto.setCreatedTime(new Date());
        ResponseResult responseResult = articleClient.saveArticle(articleDto);
        return responseResult;
    }

    private Boolean handleImageScan(List<String> images, WmNews wmNews) {
        Boolean flag=true;
        try {
            if(images==null){
                return flag;
            }
            Stream<String> distinct = images.stream().distinct();
            List<byte[]> imagesList=new ArrayList<>();
            images.forEach(item->{
                if(StringUtils.isNotBlank(item)){
                    imagesList.add(fileStorageService.downLoadFile(item));
                }
            });
            Map map = greenImageScan.imageScan(imagesList);
            if(map!=null){
                if(map.get("suggestion").equals("block")){
                    flag=false;
                    wmNews.setStatus(WmNews.Status.FAIL.getCode());
                    wmNews.setReason("当前图片中存在违规内容");
                    wmNewsMapper.updateById(wmNews);
                }
                if(map.get("suggestion").equals("review")){
                    flag=false;
                    wmNews.setStatus(WmNews.Status.ADMIN_AUTH.getCode());
                    wmNews.setReason("当前图片中存在不确定内容");
                    wmNewsMapper.updateById(wmNews);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    private Boolean handleTextScan(String text, WmNews wmNews) {
        Boolean flag=true;
        try {
            Map map = greenTextScan.greeTextScan(text);
            if(map!=null){
                if(map.get("suggestion").equals("block")){
                    flag=false;
                    wmNews.setStatus(WmNews.Status.FAIL.getCode());
                    wmNews.setReason("当前文章中存在违规内容");
                    wmNewsMapper.updateById(wmNews);
                }
                if(map.get("suggestion").equals("review")){
                    flag=false;
                    wmNews.setStatus(WmNews.Status.ADMIN_AUTH.getCode());
                    wmNews.setReason("当前文章中存在不确定内容");
                    wmNewsMapper.updateById(wmNews);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }


    private Map<String, Object> handleTextAndImages(WmNews wmNews) {
        String title = wmNews.getTitle();
        String content = wmNews.getContent();
        String labels = wmNews.getLabels();
        //将文字内容和图片分离
        List<String> listImages=new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        List<Map> list= JSONArray.parseArray(content,Map.class);
        HashMap hashMap = new HashMap();
        hashMap.put("type", "text");
        hashMap.put("value", title);

        HashMap hashMap1 = new HashMap();
        hashMap1.put("type", "text");
        hashMap1.put("value", labels);
        list.add(hashMap);
        for (Map map : list) {
            if(map.get("type").equals("text")){
                String o = (String)map.get("value");
                sb.append(o);
            }
            if(map.get("type").equals("image")){
                String value = (String) map.get("value");
                listImages.add(value);
            }
        }
        //将封面图片存入listImages
        String images = wmNews.getImages();
        String[] split = images.split(",");
        for (String s : split) {
            listImages.add(s);
        }
        //封装数据
        Map<String, Object> map = new HashMap<>();
        map.put("text", sb.toString());
        map.put("images", listImages);
        return map;
    }


}
